<template>
  <a-spin :spinning="confirmLoading">
    <CourseTop style="margin-bottom: 70px" :item="form" :purchased="purchased" :certificate="certificate"/>
    <div class="global-main">
      <div class="banner-wrap free">
        <div class="course-banner--free">
          <div class="course-banner-inner">
            <section class="section-study">
              <div class="wrapper-player">
                <div class="player-container">
                  <div class="loki-player-wrapper" id="loki-player-wrapper">
                    <div class="tc_player react-draggable" id="course-playback-player"
                         style="transform: translate(0px, 0px);">
                      <template v-if="!!selectItem">
                        <template v-if="selectItem.resourceType === 1">
                          <video class="video" ref="playVideo" controls preload="auto" autoplay
                                 :key="selectItem.id">
                            <source :src="getVideoUrl(selectItem.resourceId)"
                                    type="video/mp4">
                          </video>
                        </template>
                        <template v-else-if="selectItem.resourceType === 2">
                          <iframe :src="url + selectItem.resourceId" frameborder="0" width="100%"
                                  height="490px"
                                  scrolling="auto"></iframe>
                        </template>
                      </template>
                    </div>
                  </div>
                  <div class="auto-play-tip" v-if="showTips">
                    您上次看到 {{ formatSeconds(currentProcess) }}，正在自动续播
                    <span @click="showTips=false">×</span>
                  </div>
                </div>
              </div>
              <div class="wrapper-player-aside">
                <div class="player-aside">
                  <div class="aside-catalogue double-layer">
                    <ul class="section-wrapper" v-for="(item, index) in form.catalogList"
                        v-if=" !!form?.catalogList  && form.catalogList.length >0 ">
                      <template v-if="item.type === 2">
                        <div :class="sectionTitleClass(item.id)" @click="updateSelectItem(item)">
                          <a-flex align="center" style="font-size: 16px">
                            <template v-if="item.resourceType === 1">
                              <PlayCircleTwoTone /> &nbsp;
                            </template>
                            <template v-else-if="item.resourceType === 2">
                              <FilePdfTwoTone /> &nbsp;
                            </template>
                            {{ index + 1 < 10 ? "0" + (index + 1) : index + 1 }}.
                            <img src="../../assets/img/trytosee.png" alt=""
                                 v-if="!form?.isFree && !!item?.tryToSee" /> {{ item.name }}
                          </a-flex>
                          <p class="task-hour" style="margin-left: 24px">
                             <span v-if="!!item?.videoHour"
                                   style="margin-right: 10px">时长{{ formatSeconds(item.videoHour)
                               }}
                          </span>
                            <span
                              v-if="!!item?.mustLearnTime"
                              style="margin-right: 10px">必学{{ formatSeconds(item.mustLearnTime)
                              }}</span>
                            <span v-if="!!item?.learnProcess">{{ item.learnProcess }}</span>
                          </p>
                        </div>
                      </template>
                      <template v-else>
                        <p :class="sectionTitleClass(item.id)">
                          {{ index + 1 < 10 ? "0" + (index + 1) : index + 1 }}. {{ item.name }}</p>
                      </template>
                      <div :class="taskItemClass(child.id)"
                           v-for="(child, cIndex) in item.childList"
                           v-if="item.type === 1  && item.childList.length >0 "
                           @click="updateSelectItem(child)">
                        <div class="task-type">
                          <template v-if="child.resourceType === 1">
                            <PlayCircleTwoTone />
                          </template>
                          <template v-else-if="child.resourceType === 2">
                            <FilePdfTwoTone />
                          </template>
                        </div>
                        <div class="task-content">
                          <p class="task-name">
                            <a-flex align="center">
                              <img src="../../assets/img/trytosee.png" alt=""
                                   v-if="!form?.isFree && !!child?.tryToSee" /> {{ child.name }}
                            </a-flex>
                          </p>
                          <p class="task-info">
                             <span v-if="!!child?.videoHour"
                                   style="margin-right: 10px">时长{{ formatSeconds(child.videoHour)
                               }}
                          </span>
                            <span v-if="!!child?.mustLearnTime"
                                  style="margin-right: 10px">必学{{ formatSeconds(child.mustLearnTime)
                              }}</span>
                            <span v-if="!!child?.learnProcess">{{ child.learnProcess }}</span>
                          </p>
                        </div>
                      </div>
                    </ul>
                  </div>
                </div>
              </div>
            </section>
          </div>
        </div>
      </div>
      <div class="section-main">
        <section class="detail js-hook-detail">
          <CourseDetail :course="form" v-if="!!form" />
        </section>
        <aside class="aside" v-if="!!form?.teacherName">
          <div class="agency-info">
            <div class="agency-info-inner">
              <div class="agency-tt">
                <div class="tt-cover-url">
                  <a-avatar :src="getFileAccessHttpUrl(form?.teacherAvatar)" :size="72" />
                </div>
                <div class="tt-cover-right">
                  <div class="tt-cover-name">
                    {{ form?.teacherName }}老师
                  </div>
                  <div class="agency-hints">
                    <a-tag class="item-tt" v-for="(item,index) in form?.teacherPost?.split(',')">
                      {{ item }}
                    </a-tag>
                  </div>
                </div>
              </div>
            </div>
            <a-divider />
            <p class="kc-teacher-intro">
                  <span class="kc-teacher-intro-ellipsis">
                    {{ form?.teacherIntroduce }}
                  </span>
            </p>
          </div>
        </aside>
      </div>
    </div>
  </a-spin>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref, watchEffect } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
  apiCalcStudyTime,
  apiCheckPreTaskComplete,
  apiFindUserCatalog,
  apiGetCourseStudyDetail,
  apiGetCourseStudyProcess,
  apiGetLatestStudyTask,
  apiGetTaskStudyTime
} from "@/api/course";
import { apiGenerateCertificate, apiGetUserCertificate } from "@/api/certificate";

import { getFileAccessHttpUrl, getVideoUrl } from "@/utils/compUtils";
import { formatSeconds, toPercent } from "@/utils";
import { FilePdfTwoTone, PlayCircleTwoTone } from "@ant-design/icons-vue";
import CourseDetail from "@/views/course/coursedetail/CourseDetail.vue";
import { formatToDateTime } from "@/utils/dateUtil";
import { useMessage } from "@/hooks/web/useMessage";
import { useLeaveStore } from "@/store/modules/leaveExam";
import { storeToRefs } from "pinia";
import CourseTop from "@/components/course/CourseTop.vue";
import { getGoodsPurchased } from "@/api/order";

const baseApiUrl = import.meta.env.VITE_GLOB_DOMAIN_URL;
const url = ref(`${baseApiUrl}/common/pdf/preview/`);
const route = useRoute();
const courseId = route.params?.id ?? -1;
const router = useRouter();
const { createMessage, createConfirm } = useMessage();
const form: any = ref<any>();
const confirmLoading = ref<boolean>(false);
const selectItem: any = ref<any>();
const playVideo = ref();
const showTips = ref<boolean>(false);
const purchased = ref<any>(false);
const certificate = ref<any>();

async function initFormData() {
  try {
    confirmLoading.value = true;
    const data: any = await apiGetCourseStudyDetail(courseId);
    const { taskNum, finishNum, certificateId } = data.result;
    if (certificateId && finishNum >= taskNum) {
      apiGenerateCertificate(certificateId, "", courseId);
      const result: any = await apiGetUserCertificate(certificateId, "", courseId);
      certificate.value = result?.result;
    }
    //设置课程任务学习进度
    await setCourseStudyProcess(data.result);
    form.value = { ...data.result };
    //初始化默认要学习的任务
    await initSelectItem();
    //课程是否已经购买
    const res: any = await getGoodsPurchased(courseId);
    purchased.value = res?.result;
  } finally {
    confirmLoading.value = false;
  }
}

/**
 * 设置课程任务学习进度
 * @param data
 */
async function setCourseStudyProcess(data) {
  const taskProcessList: any = await apiGetCourseStudyProcess(courseId);
  if (!!data && data.catalogList?.length > 0) {
    data.catalogList.forEach((item: any) => {
      if (item.type === 1 && item.childList?.length > 0) {//目录
        item.childList.forEach((child) => {
          setItemProcess(taskProcessList.result, child);
        });
      } else if (item.type === 2) {//任务
        setItemProcess(taskProcessList.result, item);
      }
    });
  }
}

function setItemProcess(taskProcessList, item) {
  const taskProcess: any = taskProcessList.filter((val: any) => val.courseCatalogId == item.id)[0];
  if (!!taskProcess && !!taskProcess.learnProcess) {
    item.learnProcess = taskProcess.learnProcess >= 1 ? "已学完" : "已学" + toPercent(taskProcess.learnProcess);
  }
}

//开始学习时间
let startLearnTime: any = null;

let endLearnTime: any = null;

const currentProcess = ref<any>();

/**
 * 检测付费课程是否满足学习条件
 */
function isMatchStudyCondition(item: any) {
  if (!(form.value?.isFree || (!form.value?.isFree && purchased.value) || (!form.value?.isFree && item.tryToSee))) {
    return false;
  }
  return true;
}

/**
 * 初始化默认要学习的任务
 */
async function initSelectItem() {
  //获取最近的学习记录
  const data: any = await apiGetLatestStudyTask(courseId);
  const latestData = data?.result;
  if (latestData) {
    currentProcess.value = latestData.currentProcess;
    if (!!form?.value.catalogList && form.value.catalogList.length > 0) {
      form.value.catalogList.forEach((item: any) => {
        if (item.id == latestData.courseCatalogId) {
          selectItem.value = item;
        } else if (item.childList?.length > 0) {
          item.childList.forEach((child: any) => {
              if (child.id == latestData.courseCatalogId) {
                selectItem.value = child;
              }
            }
          );
        }
      });
    }
  } else {
    if (!!form?.value.catalogList && form.value.catalogList.length > 0) {
      if (form.value.catalogList[0].type === 2) {//任务
        //检测付费课程是否满足学习条件
        if (!isMatchStudyCondition(form.value.catalogList[0])) {
          return;
        }
        selectItem.value = form.value.catalogList[0];
      } else if (!!form.value.catalogList[0]?.childList && form.value.catalogList[0].childList.length > 0) {//目录
        //检测付费课程是否满足学习条件
        if (!isMatchStudyCondition(form.value.catalogList[0].childList[0])) {
          return;
        }
        selectItem.value = form.value.catalogList[0].childList[0];
      }
    }
  }
  if (!!selectItem.value) {
    startLearnTime = new Date();
  }
}

function taskItemClass(id) {
  if (selectItem.value && id == selectItem.value.id) {
    return "task-item active";
  } else {
    return "task-item";
  }
}

function sectionTitleClass(id) {
  if (selectItem.value && id == selectItem.value.id) {
    return "section-title active";
  } else {
    return "section-title";
  }
}


/**
 * 更新当前正在学习的任务
 * @param item
 */
async function updateSelectItem(item) {
	console.log("触发更新当前正在学习的任务！！！！")
  //检测付费课程是否满足学习条件
  if (!isMatchStudyCondition(item)) {
    createMessage.warn("付费课程请先购买再学习");
    return;
  }
  //点击的任务不是当前正在学习的则进行切换
  if (selectItem.value && item.id != selectItem.value?.id) {
    console.log("切换正在学习的任务计算时长");
    //切换前计算学习时长
    await calcTime();

    //重新设置开始时间
    startLearnTime = new Date();

    //获取任务学习进度
    const userCatalog: any = await apiFindUserCatalog(selectItem.value.id,courseId);
    if (!!userCatalog.result && !!userCatalog.result.learnProcess) {
      selectItem.value.learnProcess = userCatalog.result.learnProcess >= 1 ? "已学完" : "已学" + toPercent(userCatalog.result.learnProcess);
    }

    //课程任务顺序解锁
    if (!!form.value?.taskSequeUnlock) {
      const result: any = await apiCheckPreTaskComplete(item.id,courseId);
      if (!result.result) {//未完成
        createMessage.error("课程任务需顺序学习，请先学完上一任务");
        return;
      }
    }
    selectItem.value = item;
    const data: any = await apiGetTaskStudyTime(item.id,courseId);
    currentProcess.value = data?.result;
  }
}


//计算学习时长
async function calcTime() {
  endLearnTime = new Date();
  if (!startLearnTime || !selectItem.value) {
    return;
  }
  let currentTime = null;
  if (selectItem.value.resourceType == 1 && !!playVideo.value) {
    currentTime = playVideo.value.currentTime;
  }
  let params = {
	  courseId: courseId,
    courseCatalogId: selectItem.value.id,
    startLearnTime: startLearnTime ? formatToDateTime(startLearnTime) : null,
    endLearnTime: endLearnTime ? formatToDateTime(endLearnTime) : null,
    currentProcess: currentTime
  };
  await apiCalcStudyTime(params);
}


//*****************切屏监听**********************//
const leaveStore = useLeaveStore();
const { isLocked, isLeave } = storeToRefs(leaveStore);
//切换选项卡，最小化窗口监听
document.addEventListener("visibilitychange", () => {
  let state = document.visibilityState;
  if (!isLocked.value) {
    if (state == "hidden") { //切换标签页
      console.log("切换选项卡，最小化窗口计算学习时长");
      //计算学习时间
      if (!isLeave.value) {
        leaveStore.setIsLeave(true);
        calcTime();
      }
    } else { //又切换回来
      //重新设置开始时间
      console.log("切屏回来");
      startLearnTime = new Date();
      leaveStore.setIsLeave(false);
    }
  }
});


//************定时检测鼠标移动，点击事件，检测是否处于学习状态*************//
let mouseTimer: any = null;  // 声明一个鼠标计时器变量
onMounted(async () => {
  leaveStore.setIsLeave(false);
  leaveStore.setIsLocked(false);

  //监听浏览器刷新和关闭事件
  window.addEventListener("beforeunload", handleBeforeUnload);
  window.scrollTo(0, 0);//页面加载完成后自动滚动到顶部

  await initFormData();

  if (!!form.value?.leaveOn) { //课程是否设置弹窗防呆
    const leaveTimeAlert = form.value?.leaveTimeAlert ?? 10;//单位为分钟
    document.onmousemove = () => { // 监听鼠标移动事件
      if (mouseTimer) {
        clearTimeout(mouseTimer); // 清除之前的鼠标计时器
      }
      mouseTimer = setTimeout(() => {
        //暂停视频
        if (!!playVideo.value && !playVideo.value?.paused) {
          playVideo.value.pause();
        }
        if (!isLocked.value) {
          //锁定
          leaveStore.setIsLocked(true);

          //未移动鼠标的提示
          noStudyAlert();

          if (!isLeave.value) {
            console.log("未鼠标移动计算学习时长");
            //提交学习时间
            calcTime();
          }
        }
      }, leaveTimeAlert * 60000);
    };
  }
});


//未处于学习状态时的提示框
function noStudyAlert() {
  createConfirm({
    iconType: "warning",
    title: "提示",
    content: "检测到您已离开当前屏幕，请您继续学习课程！",
    okText: "我知道了",
    onOk: () => {
      startLearnTime = new Date();
      //释放锁定
      leaveStore.setIsLocked(false);

      //播放视频
      if (!!playVideo.value && !!playVideo.value?.paused) {
        playVideo.value.play();
      }
    },
    // 隐藏掉取消按钮
    cancelButtonProps: { style: { display: "none" } }
  });
}

watchEffect(() => {
    if (playVideo.value) {
      //禁止拖动进度条
      videoNoDragg();
      if (!!currentProcess.value) {
        playVideo.value.currentTime = currentProcess.value;
        showTips.value = true;
        setTimeout(() => showTips.value = false, 10000);
      }
    }
  }
);

//禁止拖动进度条
function videoNoDragg() {
  if (!!playVideo.value && !!form.value?.videoNodragg) {
    let last = 0;
    playVideo.value.ontimeupdate = function() {
      let current = playVideo.value.currentTime;
      if (current - last > 2) {
        playVideo.value.currentTime = last;
      } else {
        last = current;
      }
    };
  }
}

async function handleBeforeUnload() {
  console.log("handleBeforeUnload被调用");
  //计算学习时间
  await calcTime();
  startLearnTime = new Date();
}

//页面销毁前解除监听
onBeforeUnmount(async () => {
  console.log("刷新或者关闭浏览器计算时长");
  await calcTime();
  leaveStore.setIsLeave(true);
  //清除定时器
  if (mouseTimer) {
    clearTimeout(mouseTimer);
  }
  document.onmousemove = null;
  window.removeEventListener("beforeunload", handleBeforeUnload);
});

</script>

<style scoped>
.global-main {
  background-color: #f5f8fa;
}

.banner-wrap {
  border-radius: 20px;
  background-color: #fff;
  padding: 30px 0;
}

.banner-wrap.free {
  margin-bottom: 20px;
}

.course-banner-hd, .course-banner-inner {
  width: 1200px;
  margin: 0 auto;
}

.course-banner--free .section-study {
  display: flex;
  height: 500px;
  background: #1b2128;
  border: 1px solid #c0c5cc;
}

.course-banner--free .wrapper-player {
  -webkit-flex: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;
}

.player-container {
  height: 100%;
  width: 100%;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}

.loki-player-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.loki-player-wrapper .tc_player {
  width: 100%;
  height: 100%;
}

.course-banner--free .wrapper-player-aside {
  width: 360px;
  height: 100%;
}

.player-aside {
  height: 100%;
}

.aside-catalogue {
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  background: #1b2128;
  padding-bottom: 12px;
}

.aside-catalogue .section-wrapper {
  padding-top: 12px;
}

.aside-catalogue .section-wrapper .section-title {
  padding: 3px 24px;
  font-size: 16px;
  color: #a1a9b2;
  cursor: default;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  word-wrap: normal;
}

.aside-catalogue .section-wrapper .section-title.active,
.aside-catalogue .section-wrapper .section-title.active .task-hour {
  background: #0f1419;
  border-radius: 16px;
  font-weight: 400;
  color: #3f7dee;
}

.aside-catalogue .task-item {
  height: 64px;
  margin: 0 12px;
  padding: 12px;
  display: flex;
  cursor: pointer;
}

.aside-catalogue .task-item .task-content {
  width: calc(100% - 28px);
}

.aside-catalogue .task-item .task-content .task-name {
  height: 26px;
  line-height: 26px;
  font-size: 14px;
  color: #a1a9b2;
  margin-bottom: 4px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  word-wrap: normal;
}

.task-hour, .aside-catalogue .task-item .task-content .task-info {
  height: 16px;
  line-height: 16px;
  font-size: 13px;
  color: #667280;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  word-wrap: normal;
}

.aside-catalogue .task-item.active {
  background: #0f1419;
  border-radius: 16px;
  font-weight: 400;
  color: #3f7dee !important;
}

.course-banner--free .course-opbar, .course-banner--free .course-opbar .operate-btn {
  color: #8797a1;
  display: flex;
  align-items: center;
}

.course-banner--free .course-opbar {
  height: 45px;
  padding: 20px;
}

.nav-comment-wrapper {
  position: relative;
}

.nav-comment-wrapper:hover {
  cursor: pointer;
  color: #0a9fe5;
}

.course-banner--free .course-opbar-item {
  font-size: 14px;
  line-height: 20px;
  display: flex;
  align-items: center;
  margin-right: 20px;
  cursor: pointer;
  color: #cc8500;
}

a {
  color: inherit;
  text-decoration: none;
}

.aside-catalogue .task-item.active .task-content .task-info,
.aside-catalogue .task-item.active .task-content .task-name {
  color: #2080f7;
}

.aside-catalogue .task-item .task-type {
  display: flex;
  width: 16px;
  height: 20px;
  margin: 3px 10px 3px 0;
}

video {
  width: calc(100%);
  height: calc(100%);
  object-fit: contain;
}

.course-banner--free .section-bottom {
  display: flex;
  align-items: center;
  padding: 24px 0;
}

.course-banner--free .section-bottom .wrapper-info {
  display: flex;
  align-items: center;
  -webkit-flex: 1;
  flex: 1;
}

.course-banner--free .course-info {
  flex: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 0;
}

.course-banner--free .course-title {
  font-size: 24px;
  line-height: 32px;
  color: #0f1419;
  max-width: calc(1200px - 360px);
  flex: 1 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  word-wrap: normal;
}

.course-banner--free .course-hints {
  font-size: 14px;
  line-height: 20px;
  color: #667280;
  margin-right: 32px;
  display: flex;
  align-items: center;
}

.course-banner--free .course-price {
  font-size: 24px;
  line-height: 32px;
  color: #ff7a38;
}

.course-banner--free .course-nums {
  margin-left: 16px;
}

.section-main {
  width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
}

:deep(.ant-breadcrumb) {
  line-height: 3;
  font-size: 15px;
}

.detail {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 3px 12px rgba(0, 36, 153, .06);
  width: 820px;
}

.agency-info {
  width: 360px;
  padding-top: 8px;
  position: relative;
  margin-bottom: 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 3px 12px rgba(0, 36, 153, .06);
}

.agency-info-inner {
  border-radius: 12px;
  padding: 24px 20px 10px;
  background-color: #fff;
  position: relative;
}

.agency-tt {
  display: flex;
}

.agency-tt .tt-cover-url {
  width: 72px;
  height: 72px;
  margin-right: 16px;
  display: inline-block;
  -webkit-flex-shrink: 0;
  flex-shrink: 0;
}


.agency-tt .tt-cover-right {
  -webkit-flex: 1;
  flex: 1;
  min-width: 0;
}

.agency-tt .tt-cover-name {
  margin-bottom: 14px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  word-wrap: normal;
  font-size: 16px;
}

.agency-hints, .agency-hints {
  display: flex;
  align-items: center;
}

.agency-hints .item-num {
  display: inline-block;
  font-weight: 700;
  font-size: 17px;
  line-height: 20px;
  color: #3e454d;
}

.agency-hints .item-tt {
  display: inline-block;
  font-size: 13px;
  line-height: 20px;
  color: #666c80;
}

.agency-tt .tt-cover-url img {
  width: 100%;
  border-radius: 12px;
}

img {
  border: 0;
  vertical-align: middle;
  max-width: 100%;
  width: 26px;
  height: 26px;
  margin: 0 3px;
}

.kc-teacher-intro {
  width: 100%;
  padding: 10px;
  color: #586470;
}

.kc-teacher-intro .kc-teacher-intro-ellipsis {
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 24px;
}

:deep(.ant-divider-horizontal) {
  margin: 10px 0;
}

:deep( .ant-tabs-nav .ant-tabs-tab) {
  padding: 16px 25px;
}

.auto-play-tip {
  position: absolute;
  left: 20px;
  bottom: 70px;
  padding: 7px 20px;
  font-size: 12px;
  line-height: 16px;
  color: #fff;
  background: #262727;
  border-radius: 20px;
  overflow: hidden;
  z-index: 2;
}

.auto-play-tip > span {
  font-size: 16px;
  width: 20px;
  margin-left: 10px;
  text-align: center;
  cursor: pointer;
}
</style>
